package com.example.zy.car.custom;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;

import java.io.IOException;
import java.util.List;

/**
 * 封装一个摄像头和一个图形渲染一个中心预览照相机表面。
 * 我们需要中心SurfaceView因为并不是所有的设备有摄像头，
 * 支持预览大小相同的纵横比为设备的显示。
*/
public class Preview extends ViewGroup implements SurfaceHolder.Callback {
 private final String TAG = "Preview";
 private final int width=this.getWidth();
 private final int height=this.getHeight();
 SurfaceView mSurfaceView;
 SurfaceHolder mHolder;
 Size mPreviewSize;
 List<Size> mSupportedPreviewSizes;
 Camera mCamera;
 public Preview(Context context, AttributeSet attrs) {
     super(context,attrs);
     mSurfaceView = new SurfaceView(context);
     addView(mSurfaceView);
     mHolder = mSurfaceView.getHolder();
     mHolder.addCallback(this);
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 }
 public Preview(Context context) {
	 this(context,null);
 }

 public void setCamera(Camera camera) {
     mCamera = camera;
     if (mCamera != null) {
         mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
         requestLayout();
     }
 }

 public void switchCamera(Camera camera) {
    setCamera(camera);
    try {
        camera.setPreviewDisplay(mHolder);
    } catch (IOException exception) {
        Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
    }
    Camera.Parameters parameters = camera.getParameters();
    parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
    requestLayout();

    camera.setParameters(parameters);
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
     final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
     setMeasuredDimension(width, height);

     if (mSupportedPreviewSizes != null) {
         mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
     }
 }
    
    @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
     if (changed && getChildCount() > 0) {
         final View child = getChildAt(0);

         final int width = r - l;
         final int height = b - t;

         int previewWidth = width;
         int previewHeight = height;
         if (mPreviewSize != null) {
             previewWidth = mPreviewSize.width;
             previewHeight = mPreviewSize.height;
         }
         
         if (width * previewHeight > height * previewWidth) {
             final int scaledChildWidth = previewWidth * height / previewHeight;
             child.layout((width - scaledChildWidth) / 2, 0,
                     (width + scaledChildWidth) / 2, height);
         } else {
             final int scaledChildHeight = previewHeight * width / previewWidth;
             child.layout(0, (height - scaledChildHeight) / 2,
                     width, (height + scaledChildHeight) / 2);
         }
     }
 }

 public void surfaceCreated(SurfaceHolder holder) {
     //创建的时候让相机呈现在surfaceHolder
     try {
         if (mCamera != null) {
             mCamera.setPreviewDisplay(holder);
         }
     } catch (IOException exception) {
         Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
     }
 }

 public void surfaceDestroyed(SurfaceHolder holder) {
     // Surface要销毁的时候回调，让preView停止
     if (mCamera != null) {
         mCamera.stopPreview();
     }
 }
 private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
     final double ASPECT_TOLERANCE = 0.1;
     double targetRatio = (double) w / h;
     if (sizes == null) return null;

     Size optimalSize = null;
     double minDiff = Double.MAX_VALUE;

     int targetHeight = h;
     
     for (Size size : sizes) {
         double ratio = (double) size.width / size.height;
         if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
         if (Math.abs(size.height - targetHeight) < minDiff) {
             optimalSize = size;
             minDiff = Math.abs(size.height - targetHeight);
         }
     }
     
     if (optimalSize == null) {
         minDiff = Double.MAX_VALUE;
         for (Size size : sizes) {
             if (Math.abs(size.height - targetHeight) < minDiff) {
                 optimalSize = size;
                 minDiff = Math.abs(size.height - targetHeight);
             }
         }
     }
     return optimalSize;
 }

 public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
     //changed的时候执行相应的操作
	 if (mCamera != null) {
		 Camera.Parameters parameters = mCamera.getParameters();
		 parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
		 requestLayout();
		 
		 mCamera.setParameters(parameters);
		 mCamera.startPreview();
	 }
 }

}
